package fun.zhaoyuanhao.facai.gen;

import cn.hutool.core.util.RandomUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 票据生成器
 *
 * @author 赵元昊
 * @date 2021/09/03 18:00
 **/
public class TicketGen {

    public static List<List<List<Integer>>> gen(List<Atom> atoms, Long size) {
        List<List<List<Integer>>> ticketList = new LinkedList<>();
        for (long i = 0; i < size; i++) {
            List<List<Integer>> ticket = new LinkedList<>();
            for (Atom atom : atoms) {
                List<Integer> numbers = new LinkedList<>();
                Atom clone = atom.clone();
                for (int j = 0; j < clone.size; j++) {
                    int index = RandomUtil.randomInt(1, Integer.MAX_VALUE) % clone.seed.size();
                    numbers.add(clone.seed.get(index));
                    clone.seed.remove(index);
                }
                numbers.sort(Integer::compareTo);
                ticket.add(numbers);
            }
            ticketList.add(ticket);
        }
        return ticketList;
    }

    public static void sout(List<List<List<Integer>>> tickets) {
        for (List<List<Integer>> ticket : tickets) {
            StringBuilder builder = new StringBuilder();
            for (List<Integer> numbers : ticket) {
                if (builder.length() != 0) {
                    builder.append("-");
                }
                builder.append(numbers.toString());
            }
            System.out.println(builder.toString());
        }
    }

    public static List<Map<Integer, Integer>> sum(List<List<List<Integer>>> tickets) {
        List<Map<Integer, Integer>> sum = new LinkedList<>();
        if (!tickets.isEmpty()) {
            List<List<Integer>> ticket = tickets.get(0);
            if (!ticket.isEmpty()) {
                for (int i = 0; i < ticket.size(); i++) {
                    sum.add(new HashMap<>() {
                        @Override
                        public Integer put(Integer key, Integer value) {
                            Integer val = 0;
                            if (this.containsKey(key)) {
                                val = this.get(key);
                            }
                            val++;
                            return super.put(key, val);
                        }
                    });
                }
            }
        }
        for (List<List<Integer>> ticket : tickets) {
            for (int i = 0; i < ticket.size(); i++) {
                Map<Integer, Integer> integerIntegerMap = sum.get(i);
                List<Integer> numbers = ticket.get(i);
                for (Integer number : numbers) {
                    integerIntegerMap.put(number, null);
                }
            }
        }
        return sum;
    }

    public static void soutSum(List<Map<Integer, Integer>> sum, List<Integer> size) {
        System.out.println("--------------------------开始求和----------------------------");
        List<List<Integer>> facai = new LinkedList<>();
        for (int i = 0; i < sum.size(); i++) {
            Map<Integer, Integer> integerIntegerMap = sum.get(i);
            System.out.println("------------------------------------------------------------");
            List<Map.Entry<Integer, Integer>> result = integerIntegerMap.entrySet().stream()
                    .sorted((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue())).collect(Collectors.toList());
            StringBuilder stringBuilder = new StringBuilder();
            for (Map.Entry<Integer, Integer> integerIntegerEntry : result) {
                if (stringBuilder.length() != 0) {
                    stringBuilder.append("\n");
                }
                stringBuilder.append("球号：" + integerIntegerEntry.getKey() + "   中奖次数:" + integerIntegerEntry.getValue());
            }
            facai.add(result.subList(0, size.get(i)).stream().map(Map.Entry::getKey).sorted().collect(Collectors.toList()));
            System.out.println(stringBuilder.toString());
        }
        System.out.println("--------------------------今日发财----------------------------");
        StringBuilder stringBuilder = new StringBuilder();
        for (List<Integer> integers : facai) {
            if (stringBuilder.length() != 0) {
                stringBuilder.append("-");
            }
            stringBuilder.append(integers.toString());
        }
        System.out.println(stringBuilder.toString());
    }

    public static class TicketBuilder {

        public static TicketBuilder builder() {
            return new TicketBuilder();
        }

        private List<Atom> atoms = new LinkedList<>();

        private Long size = 1L;

        public TicketBuilder size(Long size) {
            this.size = size;
            return this;
        }

        public TicketBuilder add(List<Integer> seed, Integer size) {
            atoms.add(Atom.builder().seed(seed).size(size).build());
            return this;
        }

        public TicketBuilder add(List<Integer> seed) {
            atoms.add(Atom.builder().seed(seed).size(1).build());
            return this;
        }

        public List<List<List<Integer>>> gen() {
            return TicketGen.gen(atoms, size);
        }

        public void sout() {
            TicketGen.sout(TicketGen.gen(atoms, size));
        }

        public List<Map<Integer, Integer>> sum() {
            return TicketGen.sum(TicketGen.gen(atoms, size));
        }

        public void soutSum() {
            TicketGen.soutSum(TicketGen.sum(TicketGen.gen(atoms, size)), atoms.stream().map(Atom::getSize).collect(Collectors.toList()));
        }

    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Atom implements Cloneable {
        private List<Integer> seed;
        private Integer size;

        @Override
        public Atom clone() {
            List<Integer> seedCopy = new LinkedList<>();
            seedCopy.addAll(seed);
            return new Atom(seedCopy, size.intValue());
        }
    }
}
